﻿using CMFrameWork.Common;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using hutil;

namespace hconnect {
    public class ModbusTcpConnect:SocketZtTaskConnect {
        protected short transaction_id = 0;
        protected byte _identifier;
        protected override bool init() {
            base.init();
            this._identifier = Convert.ToByte(ip.Split('.')[3].ToInt32(0));
            return true;
        }
        public byte[] Receive(int len) {
            byte[] array = ReadTelex(len);
            ModbusUtil.CheckErr(array,transaction_id,_identifier);
            return array;
        }
        public byte[] Receive() {
            byte[] array = ReadTelex(256);
            ModbusUtil.CheckErr(array,transaction_id,_identifier);
            return array;
        }
        public byte[] ZeroingRegisters(ushort len) {//拼接报文并发送
            byte[] result;
            bool flag2 = len > 123;
            if(flag2) {
                return null;
            }
            ushort message_len = (ushort)(7 + len * 2);
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(16);
            list.AddRange(ModbusUtil.GetBytes(0));
            list.AddRange(ModbusUtil.GetBytes(len));
            list.Add((byte)(len * 2));
            for(int i = 0;i < (int)len;i++) {
                list.AddRange(ModbusUtil.GetBytes(0));
            }
            bool flag3 = this.Send(list.ToArray());
            if(flag3) {
                result = this.Receive();
            } else {
                result = null;
            }
            return result;
        }
        public byte[] ReadCoils(ushort start_address,ushort len) {
            byte[] first = ModbusUtil.BuildMBAPHeader(this._identifier,len);
            byte[] second = ModbusUtil.BulidReadCoilsTelex(start_address,len);
            byte[] result;
            byte[] buffer = first.Concat(second).ToArray<byte>();
            bool flag2 = this.Send(buffer);
            if(flag2) {
       
                result = this.Receive();
            } else {
                result = null;
            }
            return result;
        }
        public byte[] ReadDiscreteInputs(ushort start_address,ushort len) {
            byte[] result;
            bool flag2 = len > 2000;
            if(flag2) {
                result = null;
            } else {
                ushort message_len = 6;
                byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
                List<byte> list = new List<byte>();
                list.AddRange(collection);
                list.Add(2);
                list.AddRange(ModbusUtil.GetBytes(start_address));
                list.AddRange(ModbusUtil.GetBytes(len));
                bool flag3 = this.Send(list.ToArray());
                if(flag3) {
                   
                    result = this.Receive();
                } else {
                    throw new Exception(ip+"+"+port+"网络异常");
                    result = null;
                }
            }
            return result;
        }
        public byte[] ReadHoldingRegisters(ushort start_address,ushort len) {
            byte[] buffer = ModbusUtil.readHoldingRegistersHeader(this._identifier,start_address,len);
            bool flag2 = this.Send(buffer);
            if(flag2) {
            
                return this.Receive(len * 2 + 9);
            }
            return null;
        }
        public byte[] ReadInputRegisters(ushort start_address,ushort len) {
            byte[] result=null;
            if(len > 125) {
                return null;
            }
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(4);
            list.AddRange(ModbusUtil.GetBytes(start_address));
            list.AddRange(ModbusUtil.GetBytes(len));
            bool flag3 = this.Send(list.ToArray());
            if(flag3) {
             
                result = this.Receive();
            }
            return result;
        }
        public byte[] WriteSingleCoil(ushort address,bool value) {
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(5);
            list.AddRange(ModbusUtil.GetBytes(address));
            list.AddRange(ModbusUtil.GetBytes(value ? 65280 : 0));
            bool flag = this.Send(list.ToArray());
            byte[] result=null;
            if(flag) {
            
                result = this.Receive();
            } 
            return result;
        }
        public byte[] WriteSingleRegisters(ushort address,ushort value) {
            ushort message_len = 6;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(6);
            list.AddRange(ModbusUtil.GetBytes((short)address));
            list.AddRange(ModbusUtil.GetBytes((short)value));
            bool flag = this.Send(list.ToArray());
            byte[] result=null;
            if(flag) {
              
                result = this.Receive();
            } 
            return result;
        }
        public byte[] WriteMultipleCoils(ushort start_address,bool[] values) {
            byte[] result=null;
            bool flag3 = values.Length > 1968;
            if(flag3) {
                return  null;
            } 
                byte b = (byte)(values.Length / 8 + ((values.Length % 8 == 0) ? 0 : 1));
                ushort message_len = (ushort)(7 + b);
                byte[] array = new byte[(int)b];
                BitArray bitArray = new BitArray(values);
                bitArray.CopyTo(array,0);
                byte[] array2 = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
                List<byte> list = new List<byte>();
                list.Add(15);
                list.AddRange(ModbusUtil.GetBytes(start_address));
                list.AddRange(ModbusUtil.GetBytes((ushort)values.Length));
                list.Add(b);
                list.AddRange(array);
                bool flag4 = this.Send(list.ToArray());
                if(flag4) {
               
                    result = this.Receive();
                } 
            return result;
        }
        public byte[] MaskWriteRegister(ushort address,ushort and_mask,ushort or_mask) {
            ushort message_len = 8;
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(22);
            list.AddRange(ModbusUtil.GetBytes((short)address));
            list.AddRange(ModbusUtil.GetBytes(and_mask));
            list.AddRange(ModbusUtil.GetBytes(or_mask));
            bool flag = this.Send(list.ToArray());
            byte[] result=null;
            if(flag) {
             
                result = this.Receive();
            } 
            return result;
        }
        public byte[] WriteMultipleRegisters(ushort start_address,ushort[] values) {
            byte[] result=null;
            bool flag3 = values.Length > 123;
            if(flag3) {
              return  null;
            } 
                ushort message_len = (ushort)(7 + values.Length * 2);
                byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
                List<byte> list = new List<byte>();
                list.AddRange(collection);
                list.Add(16);
                list.AddRange(ModbusUtil.GetBytes((short)start_address));
                list.AddRange(ModbusUtil.GetBytes((short)values.Length));
                list.Add((byte)(values.Length * 2));
                for(int i = 0;i < values.Length;i++) {
                    list.AddRange(ModbusUtil.GetBytes(values[i]));
                }
                bool flag4 = this.Send(list.ToArray());
                if(flag4) {
                  
                    result = this.Receive();
                }
            return result;
        }

        public byte[] WriteRegisters(ushort start_address ,byte[] b) {
            byte[] result = null;
            bool flag3 = b.Length > 123;
            if( flag3 ) {
                return null;
            }
            ushort message_len = ( ushort ) (7 + b.Length );
            byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier ,message_len);
            List<byte> list = new List<byte>();
            list.AddRange(collection);
            list.Add(16);
            list.AddRange(ModbusUtil.GetBytes(( short ) start_address));
            list.AddRange(ModbusUtil.GetBytes(( short ) (b.Length/2)));
            list.Add(( byte ) b.Length );
            list.AddRange(b);
            
            bool flag4 = this.Send(list.ToArray());
            if( flag4 ) {
                result = this.Receive();
            }
            return result;
        }
        public byte[] ReadWriteMultipleRegisters(ushort read_start_address,ushort read_len,ushort write_start_address,ushort[] write_values) {
            byte[] result=null;
            bool flag3 = read_len > 125 || write_values.Length > 121;
            if(flag3) {
               return null;
            }
                ushort message_len = (ushort)(11 + write_values.Length * 2);
                byte[] collection = ModbusUtil.BuildMBAPHeader(this._identifier,message_len);
                List<byte> list = new List<byte>();
                list.AddRange(collection);
                list.Add(23);
                list.AddRange(ModbusUtil.GetBytes(read_start_address));
                list.AddRange(ModbusUtil.GetBytes(write_start_address));
                list.AddRange(ModbusUtil.GetBytes((ushort)write_values.Length));
                list.Add((byte)(write_values.Length * 2));
                for(int i = 0;i < write_values.Length;i++) {
                    list.AddRange(ModbusUtil.GetBytes(write_values[i]));
                }
                bool flag4 = this.Send(list.ToArray());
                if(flag4) {
               
                    result = this.Receive();
                }
            return result;
        }
    }
}
